﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web;
using System.Xml.Linq;

namespace LastFmClient
{
    public class Track : Client
    {

        private string m_TrackTagsUrl = "http://ws.audioscrobbler.com/1.0/track/*ARTISTNAME*/*TRACKNAME*/toptags.xml";
        private string m_SimilarTracksUrl = "http://ws.audioscrobbler.com/1.0/track/*ARTISTNAME*/*TRACKNAME*/similar.xml";

        public Track(string TrackName, string ArtistName)
        {
            if (string.IsNullOrEmpty(TrackName))
                throw new Exception("Track name is null or empty.");

            if (string.IsNullOrEmpty(ArtistName))
                throw new Exception("Artist name is null or empty.");

            m_TrackTagsUrl = m_TrackTagsUrl.Replace("*ARTISTNAME*", HttpUtility.UrlEncode(ArtistName));
            m_TrackTagsUrl = m_TrackTagsUrl.Replace("*TRACKNAME*", HttpUtility.UrlEncode(TrackName));
            //m_TrackTagsUrl = HttpUtility.UrlEncode(m_TrackTagsUrl);

            m_SimilarTracksUrl = m_SimilarTracksUrl.Replace("*ARTISTNAME*", HttpUtility.UrlEncode(ArtistName));
            m_SimilarTracksUrl = m_SimilarTracksUrl.Replace("*TRACKNAME*", HttpUtility.UrlEncode(TrackName));
            //m_SimilarTracksUrl = HttpUtility.UrlEncode(m_SimilarTracksUrl);

            m_TrackName = TrackName;
            m_ArtistName = ArtistName;
        }

        private string m_TrackName;
        public string Name
        {
            get
            {
                return m_TrackName;
            }
        }

        private string m_ArtistName;
        public string ArtistName
        {
            get
            {
                return m_ArtistName;
            }
        }

        private Artist m_Artist;
        public Artist Artist
        {
            get
            {
                if (m_Artist == null)
                    m_Artist = new Artist(ArtistName);

                return m_Artist;
            }
        }

        //similar songs

        private XElement m_SimilarTracksRoot;
        private XElement SimilarTracksRoot
        {
            get
            {
                if (m_SimilarTracksRoot == null)
                {
                    m_SimilarTracksRoot = GetXElement(m_SimilarTracksUrl);
                }
                return m_SimilarTracksRoot;
            }
        }

        public IEnumerable<SimilarTrack> SimilarTracks
        {
            get
            {
                IEnumerable<SimilarTrack> simTracks =
                    from el in SimilarTracksRoot.Elements()
                    select new SimilarTrack(el);

                return simTracks;
            }
        }

        public SimilarTrack TopSimilarTrack
        {
            get
            {
                return SimilarTracks.OrderByDescending(p => p.Match).First();
            }
        }

        // tags

        private XElement m_TagsRoot;
        private XElement TagsRoot
        {
            get
            {
                if (m_TagsRoot == null)
                {
                    m_TagsRoot = GetXElement(m_TrackTagsUrl);
                }

                return m_TagsRoot;
            }
        }

        public IEnumerable<Tag> Tags
        {
            get
            {
                IEnumerable<Tag> tags =
                    from el in TagsRoot.Elements("tag")
                    select new Tag(el);

                return tags;
            }
        }

        public Tag TopTag
        {
            get
            {
                return Tags.OrderByDescending(p => p.Count).First();
            }
        }

        public IEnumerable<Tag> Top5Tags
        {
            get
            {
                return GetTopNTags(5);
            }
        }

        public IEnumerable<Tag> GetTopNTags(int n)
        {
            return Tags.OrderByDescending(p => p.Count).Take(n);
        }
    }
}
